/*
 * Copyright (C) 2013-2019 Federico Iosue (federico@iosue.it)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package it.feio.android.omninotes.utils;

import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import it.feio.android.omninotes.R;


public class AnimationsHelper {

  private AnimationsHelper () {}

  public static void zoomListItem (Context context, final View view, ImageView expandedImageView, View targetView,
      AnimatorListenerAdapter animatorListenerAdapter) {
    final long animationDuration = context.getResources().getInteger(R.integer.zooming_view_anim_time);

    // Calculate the starting and ending bounds for the zoomed-in image.
    final Rect startBounds = new Rect();
    final Rect finalBounds = new Rect();
    final Point globalOffset = new Point();

    // The start bounds are the global visible rectangle of the thumbnail,
    // and the final bounds are the global visible rectangle of the container
    // view. Also set the container view's offset as the origin for the
    // bounds, since that's the origin for the positioning animation
    // properties (X, Y).
    view.getGlobalVisibleRect(startBounds);
    targetView.getGlobalVisibleRect(finalBounds, globalOffset);
    startBounds.offset(-globalOffset.x, -globalOffset.y);
    finalBounds.offset(-globalOffset.x, -globalOffset.y);

    // Adjust the start bounds to be the same aspect ratio as the final
    // bounds using the "center crop" technique. This prevents undesirable
    // stretching during the animation. Also calculate the start scaling
    // factor (the end scaling factor is always 1.0).
    float startScale;
    if ((float) finalBounds.width() / finalBounds.height()
        > (float) startBounds.width() / startBounds.height()) {
      // Extend start bounds horizontally
      startScale = (float) startBounds.height() / finalBounds.height();
      float startWidth = startScale * finalBounds.width();
      float deltaWidth = (startWidth - startBounds.width()) / 2;
      startBounds.left -= deltaWidth;
      startBounds.right += deltaWidth;
    } else {
      // Extend start bounds vertically
      startScale = (float) startBounds.width() / finalBounds.width();
      float startHeight = startScale * finalBounds.height();
      float deltaHeight = (startHeight - startBounds.height()) / 2;
      startBounds.top -= deltaHeight;
      startBounds.bottom += deltaHeight;
    }

    // Hide the thumbnail and show the zoomed-in view. When the animation
    // begins, it will position the zoomed-in view in the place of the
    // thumbnail.
    view.setAlpha(0f);
    expandedImageView.setVisibility(View.VISIBLE);

    // Construct and run the parallel animation of the four translation and
    // scale properties (X, Y, SCALE_X, and SCALE_Y).
    AnimatorSet set = new AnimatorSet();
    set.play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left, finalBounds.left))
       .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top, finalBounds.top))
       .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale, 1f))
       .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale, 1f));
    set.setDuration(animationDuration);
    set.setInterpolator(new DecelerateInterpolator());
    set.addListener(animatorListenerAdapter);
    set.start();
  }


  public static void expandOrCollapse (final View v, boolean expand) {
    TranslateAnimation anim;
    if (expand) {
      anim = new TranslateAnimation(0.0f, 0.0f, -v.getHeight(), 0.0f);
      v.setVisibility(View.VISIBLE);
    } else {
      anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, -v.getHeight());
      Animation.AnimationListener collapselistener = new Animation.AnimationListener() {
        @Override
        public void onAnimationStart (Animation animation) {
          // Useless
        }


        @Override
        public void onAnimationRepeat (Animation animation) {
          // Useless
        }


        @Override
        public void onAnimationEnd (Animation animation) {
          v.setVisibility(View.GONE);
        }
      };

      anim.setAnimationListener(collapselistener);
    }

    anim.setDuration(300);
    anim.setInterpolator(new AccelerateInterpolator(0.5f));
    v.startAnimation(anim);
  }
}
